// Bristleback plugin - Copyright (c) 2010 bristleback.googlecode.com
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
// This library is distributed in the hope that it will be useful,
// but without any warranty; without even the implied warranty of merchantability
// or fitness for a particular purpose.
// You should have received a copy of the GNU Lesser General Public License along
// with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
// ---------------------------------------------------------------------------
package pl.bristleback.server.bristle.config;

import org.apache.log4j.Logger;
import pl.bristleback.server.bristle.messages.MessageContainer;
import pl.bristleback.server.bristle.messages.MessageDispatcher;
import pl.bristleback.server.bristle.messages.MessageSender;
import pl.bristleback.server.bristle.messages.SingleThreadedMessageDispatcher;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Default implementation of {@link MessageContainerResolver} interface.
 * This implementation takes all message senders from configuration file.
 * Sender instances can be created by plugin or taken from Spring context.
 * {@link pl.bristleback.server.bristle.messages.MessageDispatcher} implementation can be provided by user,
 * otherwise default dispatcher will be used (as of current version, it is {@link SingleThreadedMessageDispatcher} class).
 * To know what names of settings should be used, see {@link pl.bristleback.server.bristle.config.BristleConstants} documentation.
 * <p/>
 * Created on: 2010-09-24 23:02:13 <br/>
 *
 * @author Wojciech Niemiec
 */
public final class MessageContainerDefaultResolver implements MessageContainerResolver {
  private static Logger log = Logger.getLogger(MessageContainerDefaultResolver.class.getName());

  public static final Class DEFAULT_DISPATCHER_CLASS = SingleThreadedMessageDispatcher.class;

  /**
   * Creates and returns message senders container.
   *
   * @param configuration Bristleback plugin configuration.
   * @return container of message senders and dispatcher.
   */
  public MessageContainer createMessageContainer(BristleConfiguration configuration) {
    MessageContainer container = new MessageContainer();
    MessageDispatcher dispatcher = getDispatcher(configuration);
    container.setMessageDispatcher(dispatcher);
    Map<String, MessageSender> senders = getMessageSenders(configuration);
    container.setSenders(senders);
    return container;
  }

  public void assignDispatcherToSenders(MessageContainer messageContainer) {
    MessageDispatcher dispatcher = messageContainer.getMessageDispatcher();
    for (MessageSender sender : messageContainer.getSenders().values()) {
      sender.setMessageDispatcher(dispatcher);
    }
  }

  private Map<String, MessageSender> getMessageSenders(BristleConfiguration configuration) {
    Map<String, MessageSender> senders = new HashMap<String, MessageSender>();

    List<ClassConfiguration> senderInformationList = getSenderInformationList(configuration);
    //todo-wojtek export senders to configuration
    for (ClassConfiguration senderInformation : senderInformationList) {
      MessageSender sender = getSender(senderInformation);
      senders.put(senderInformation.getName(), sender);
    }
    return senders;
  }

  private MessageSender getSender(ClassConfiguration senderInformation) {
    return ClassConfigurationUtil.getInstanceFromConfiguration(MessageSender.class, senderInformation);
  }

  private List<ClassConfiguration> getSenderInformationList(BristleConfiguration configuration) {
    return ClassConfigurationUtil
      .getClassConfigurationsFromSettingsMap(BristleConstants.MESSAGE_SENDER_SETTING_KEY_PREFIX, configuration.getSettings());
  }

  private MessageDispatcher getDispatcher(BristleConfiguration configuration) {
    return configuration.getMessageDispatcher();
  }
}
